//The MIT License
//
//Copyright (c) 2009 nodchip
//
//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:
//
//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.
//
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.
package tv.dyndns.kishibe.server;

import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import tv.dyndns.kishibe.client.Constant;
import tv.dyndns.kishibe.client.packet.PacketUserData;

public class ServiceIconUpload extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
	private static final long serialVersionUID = -7542423724548967280L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		FileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setSizeMax(64L * 1024L);
		List<FileItem> items = null;

		try {
			items = upload.parseRequest(request);
		} catch (Exception e) {
			System.err.println("ServiceIconUpload.doPost() リクエストのパースに失敗しました");
			e.printStackTrace();
			writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_FAILED_TO_PARSE_REQUEST);
			return;
		}

		String userCode = null;
		byte[] data = null;
		String uploadFileName = null;

		for (FileItem item : items) {
			if (item.isFormField()) {
				final String key = item.getFieldName();
				final String value = item.getString();

				if (key.equals(Constant.FORM_NAME_USER_CODE)) {
					userCode = value;
				}

			} else {
				data = item.get();

				BufferedImage image = null;
				// 画像確認
				try {
					image = ImageIO.read(new ByteArrayInputStream(data));
				} catch (Exception e) {
					System.out.println("画像ファイルの認識に失敗しました");
					e.printStackTrace();

					data = null;
					writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_FAILED_TO_DETECT_IMAGE_FILE_TYPE);
					return;
				}

				if (image == null) {
					data = null;
					writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_FAILED_TO_DETECT_IMAGE_FILE_TYPE);
					return;
				}

				image = null;

				uploadFileName = item.getName();
			}
		}

		if (userCode == null || data == null) {
			writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_REQUEST_FORMAT_ERROR);
			return;
		}

		final int offset = uploadFileName.lastIndexOf('.');
		if (offset == -1) {
			writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_IMAGE_FILE_NAME_FORMAT_ERROR);
			return;
		}
		final String extension = uploadFileName.substring(offset + 1);
		final String fileTitle = Utility.getInstance().createFileName();
		final String fileName = fileTitle + "." + extension;
		final String filePath = Constant.ICON_FOLDER_PATH + fileName;

		// ファイル書き込み
		try {
			final BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(filePath));
			outputStream.write(data);
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		// データベース書き込み
		final PacketUserData userData = CachedDatabase.getInstance().getUserData(Integer.parseInt(userCode));
		final File oldFile = new File(Constant.ICON_FOLDER_PATH + userData.imageFileName);
		if (oldFile.isFile() && !oldFile.getName().equals(Constant.ICON_NO_IMAGE)) {
			oldFile.delete();
		}
		userData.imageFileName = fileName;
		CachedDatabase.getInstance().setUserData(userData);

		// レスポンス書き込み
		writeResponse(response, Constant.ICON_UPLOAD_RESPONSE_OK);
	}

	private void writeResponse(HttpServletResponse response, String message) throws IOException {
		final BufferedWriter writer = new BufferedWriter(response.getWriter());
		writer.write(message);
		writer.close();
	}
}
